/*
 *
 * *******************************************************************
 *   @项目名称: BHex Android
 *   @文件名称: BHNetWorkController.java
 *   @Date: 11/29/18 3:21 PM
 *   @Author: chenjun
 *   @Copyright（C）: 2018 BlueHelix Inc.   All rights reserved.
 *   注意：本内容仅限于内部传阅，禁止外泄以及用于其他的商业目的.
 *  *******************************************************************
 *
 */

package io.bhex.sdk.socket;

import android.text.TextUtils;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;

import io.bhex.baselib.constant.AppData;
import io.bhex.baselib.network.listener.SimpleResponseListener;
import io.bhex.baselib.network.HttpUtils;
import io.bhex.baselib.network.params.IParams;
import io.bhex.baselib.utils.DebugLog;

public class BHNetWorkController {

    private BHSocketController mSocketClient;
    private Timer timer;
    private TimerTask timerTask;


    private Map<String, List<NetWorkRequestData>> requestMap;


    public class NetWorkRequestData<T, M> {
        public Class<T> responseClass;
        public NetWorkObserver<T> handler;
        public WebSocketBaseBean socketBaseBean;
        public IParams httpParam;

        public Class<M> responseHttpClass;
        public NetWorkObserver<M> handlerHttp;
        public int id;
    }


    public void release(){
        stopTimer();
        if(mSocketClient != null)
            mSocketClient.release();
        mSocketClient = null;
    }

    public Boolean isOpen(){
        if(mSocketClient == null )
            return false;
        return mSocketClient.isOpen();
    }

    @Deprecated
    public void disConnectSocket(){
        mSocketClient.disConnectSocket();
    }

    public BHNetWorkController(String url, boolean needLogin){
        mSocketClient = new BHSocketController(url, needLogin);
        requestMap = new ConcurrentHashMap<String, List<NetWorkRequestData>>();
    }

    private<T,M> void startTimer() {
        timer = new Timer();
        timerTask = new TimerTask() {

            @Override
            public void run() {
                if (mSocketClient== null || !mSocketClient.isOpen()) {
                    for (String key : requestMap.keySet()) {
                        final List<NetWorkRequestData> requestList = requestMap.get(key);
                        if (requestList != null) {
                            String event = "";
                            if (requestList.size() > 0 && requestList.get(0) != null) {
                                final NetWorkRequestData res = requestList.get(0);
                                if (res != null && res.httpParam != null) {
                                    if (res.handlerHttp != null && res.responseHttpClass != null) {//http回调监听
                                        HttpUtils.getInstance().request(res.httpParam, res.responseHttpClass, new SimpleResponseListener<M>() {
                                            @Override
                                            public void onSuccess(M response) {

                                                for (int i = 0; i < requestList.size(); i++) {
                                                    NetWorkRequestData request = requestList.get(i);
                                                    if (request.handlerHttp != null)
                                                        request.handlerHttp.onShowUI(response);
                                                }
                                            }

                                            @Override
                                            public void onError(Throwable error) {
                                                for (int i = 0; i < requestList.size(); i++) {
                                                    NetWorkRequestData request = requestList.get(i);
                                                    if (request.handlerHttp != null)
                                                        request.handlerHttp.onError(error.getMessage());
                                                }
                                            }
                                        });
                                    } else {    //socket回调
                                        HttpUtils.getInstance().request(res.httpParam, res.responseClass, new SimpleResponseListener<T>() {
                                            @Override
                                            public void onSuccess(T response) {
                                                for (int i = 0; i < requestList.size(); i++) {
                                                    NetWorkRequestData request = requestList.get(i);
                                                    if (request.handler != null)
                                                        request.handler.onShowUI(response);
                                                }
                                            }

                                            @Override
                                            public void onError(Throwable error) {
                                                for (int i = 0; i < requestList.size(); i++) {
                                                    NetWorkRequestData request = requestList.get(i);
                                                    if (request.handler != null)
                                                        request.handler.onError(error.getMessage());
                                                }
                                            }
                                        });
                                    }
                                    if (res.socketBaseBean != null)
                                        event = res.socketBaseBean.event;
                                }

                            }
                            if (event.equalsIgnoreCase("req"))//一次请求的socket  user使用功能 直接移除map，不做后面的定时轮询
                                requestMap.remove(key);
                        }
                    }
                }
            }
        };
        timer.schedule(timerTask, AppData.Config.TIMER_DELAY_DEFAULT_VALUE, AppData.Config.TIMER_PERIOD_DEFAULT_VALUE);
    }

    private void stopTimer(){
        if(timerTask != null)
            timerTask.cancel();
        if(timer != null) {
            //timer.purge();
            timer.cancel();
        }
        timer = null;
        timerTask = null;
    }

    public <T>  void SubRequestNetwork(final WebSocketBaseBean socketBean, IParams httpParams, Class<T> responseClass,  NetWorkObserver<T> handler){
        if(socketBean == null)
            return;
        if(TextUtils.isEmpty(socketBean.key))
            socketBean.key = socketBean.topic;
        String mapKey = socketBean.key;
        List<NetWorkRequestData> requestList;

        /*for (Map.Entry<String,List<NetWorkRequestData>>entry:requestMap.entrySet()){
            DebugLog.e("BHNetWorkController===>:",entry.getKey()+"=key=value=="+entry.getValue().size());
        }*/
        DebugLog.e("SendMessageWebSocket==>:","sub== "+mapKey+" ==keys=="+ Arrays.deepToString(requestMap.keySet().toArray()));
        if(!requestMap.containsKey(mapKey) ) {
            requestList= new LinkedList<NetWorkRequestData>();

            NetWorkRequestData requestData = new NetWorkRequestData();
            requestData.socketBaseBean = socketBean;
            requestData.responseClass = responseClass;
            requestData.handler = handler;
            requestData.httpParam = httpParams;
            int callId = -1;
            if(mSocketClient != null) {
                //真正走了订阅
                callId  = mSocketClient.SubSocketApi(socketBean, responseClass, new SocketResponseHandler<T>() {
                    @Override
                    public void onSuccess(T response) {
                        List<NetWorkRequestData> requestList = requestMap.get(socketBean.key);
                        if(requestList != null) {
                            for (int i = 0; i < requestList.size(); i++) {
                                if (requestList.get(i) != null && requestList.get(i).handler != null) {
                                    requestList.get(i).handler.onShowUI(response);
                                }
                            }
                            if(socketBean.event.equalsIgnoreCase("req") && TextUtils.isEmpty(socketBean.needReSub))
                                requestMap.remove(socketBean.key);
                        }
                    }

                    @Override
                    public void onFailed(String response) {
                        List<NetWorkRequestData> requestList = requestMap.get(socketBean.key);
                        if(requestList != null) {
                            for (int i = 0; i < requestList.size(); i++) {
                                if (requestList.get(i) != null && requestList.get(i).handler != null) {
                                    requestList.get(i).handler.onError(response);
                                }
                            }

                            if(socketBean.event.equalsIgnoreCase("req"))
                                requestMap.remove(socketBean.key);
                        }
                    }

                });
            }
            requestData.id = callId;
            requestList.add(requestData);
            requestMap.put(mapKey, requestList);
        }
        else {
            requestList = requestMap.get(mapKey);

            for (int i = 0; i < requestList.size(); i++) {
                if(requestList.get(i) != null)
                {
                    if(requestList.get(i).handler == handler)   //相同订阅不再重复创建
                        return;
                }
            }

            //新增一个观察者（未发起订阅，因为已经订阅过）
            NetWorkRequestData requestData = new NetWorkRequestData();
            requestData.socketBaseBean = socketBean;
            requestData.responseClass = responseClass;
            requestData.handler = handler;
            requestData.httpParam = httpParams;
            requestData.id = requestList.get(0).id; //同一个主题订阅 id共用
            requestList.add(requestData);
        }
        if(timer == null)
            startTimer();
    }

    //双回调订阅
    public <T,M>  void SubRequestNetwork(final WebSocketBaseBean socketBean, IParams httpParams,
                                         Class<T> responseClass,  NetWorkObserver<T> handler,
                                         Class<M> responseHttpClass,NetWorkObserver<M> handlerHttp){
        if(socketBean == null)
            return;
        if(TextUtils.isEmpty(socketBean.key))
            socketBean.key = socketBean.topic;
        String mapKey = socketBean.key;
        List<NetWorkRequestData> requestList;
        if(!requestMap.containsKey(mapKey) ) {
            requestList= new LinkedList<NetWorkRequestData>();

            NetWorkRequestData requestData = new NetWorkRequestData();
            requestData.socketBaseBean = socketBean;
            requestData.responseClass = responseClass;
            requestData.handler = handler;
            requestData.httpParam = httpParams;
            requestData.responseHttpClass = responseHttpClass;
            requestData.handlerHttp = handlerHttp;
            int callId = -1;
            if(mSocketClient != null) {
                callId  = mSocketClient.SubSocketApi(socketBean, responseClass, new SocketResponseHandler<T>() {
                    @Override
                    public void onSuccess(T response) {
                        List<NetWorkRequestData> requestList = requestMap.get(socketBean.key);
                        if(requestList != null) {
                            for (int i = 0; i < requestList.size(); i++) {
                                if (requestList.get(i) != null && requestList.get(i).handler != null) {
                                    requestList.get(i).handler.onShowUI(response);
                                }
                            }
                            if(socketBean.event.equalsIgnoreCase("req") && TextUtils.isEmpty(socketBean.needReSub))
                                requestMap.remove(socketBean.key);
                        }
                    }

                    @Override
                    public void onFailed(String response) {
                        List<NetWorkRequestData> requestList = requestMap.get(socketBean.key);
                        if(requestList != null) {
                            for (int i = 0; i < requestList.size(); i++) {
                                if (requestList.get(i) != null && requestList.get(i).handler != null) {
                                    requestList.get(i).handler.onError(response);
                                }
                            }

                            if(socketBean.event.equalsIgnoreCase("req"))
                                requestMap.remove(socketBean.key);
                        }
                    }

                });
            }
            requestData.id = callId;
            requestList.add(requestData);
            requestMap.put(mapKey, requestList);
        }
        else {

            requestList = requestMap.get(mapKey);
            //DebugLog.e("BHSocketController==>","==mapKey=="+mapKey+"==size=="+requestList.size());
            for (int i = 0; i < requestList.size(); i++) {
                if(requestList.get(i) != null)
                {
                    if(requestList.get(i).handler == handler)
                        return;
                }
            }

            NetWorkRequestData requestData = new NetWorkRequestData();
            requestData.socketBaseBean = socketBean;
            requestData.responseClass = responseClass;
            requestData.handler = handler;
            requestData.responseHttpClass = responseHttpClass;
            requestData.handlerHttp = handlerHttp;
            requestData.httpParam = httpParams;
            requestData.id = requestList.get(0).id;
            requestList.add(requestData);
        }
        if(timer == null)
            startTimer();
    }

    public void UnSubRequestNetWork(String key){
        DebugLog.e("SendMessageWebSocket==>:","unsub key=="+key);
        if(!key.isEmpty()) {
            if (requestMap.containsKey(key)) {
                List<NetWorkRequestData> requestList = requestMap.get(key);
                if(requestList != null && mSocketClient != null && requestList.size() > 0) {
                    mSocketClient.UnSubSocketApi(requestList.get(0).id);
                }
                //DebugLog.e("SendMessageWebSocket==>:","=delete=before=="+ Arrays.deepToString(requestMap.keySet().toArray()));
                requestMap.remove(key);
                DebugLog.e("SendMessageWebSocket==>:","=delete=key="+key+"=after=="+ Arrays.deepToString(requestMap.keySet().toArray()));

            }

            /*Iterator<String> iter = requestMap.keySet().iterator();        //获取key和value的set
            while (iter.hasNext()) {
                String k_key = iter.next();
                if(k_key.equals("kline_")){
                    iter.remove();
                }
            }*/
        }
    }

    public<T> void UnSubRequestNetWork(String key, final NetWorkObserver<T> handler){
        if(!key.isEmpty()) {

            if (requestMap.containsKey(key)) {

                List<NetWorkRequestData> requestList = requestMap.get(key);
                if (requestList != null && mSocketClient != null && requestList.size() > 0) {
                    int id = requestList.get(0).id;
                    for (int i = 0; i < requestList.size(); i++) {
                        NetWorkRequestData res = requestList.get(i);
                        if (res.handler == handler)
                            requestList.remove(i);
                    }

                    if (requestList.size() == 0) {
                        mSocketClient.UnSubSocketApi(id);
                        requestMap.remove(key);
                    }

                }
            }
        }
    }

}
